1.2: Layouts, Views and Resources
Contents:
- The model-view-presenter pattern
- Views
- Resource files
- Responding to view clicks
- Related practical
- Learn more
This chapter describes the screen's user interface layout and other resources you create for your app, and the code you would use to respond to a user's tap of a user interface element.
The model-view-presenter pattern
Linking an activity to a layout resource is an example of part of the model-view-presenter (MVP) architecture pattern. The MVP pattern is a well-established way to group app functions:
- Views. Views are user interface elements that display data and respond to user actions. Every element of the screen is a view. The Android system provides many different kinds of views.
- Presenters. Presenters connect the application's views to the model. They supply the views with data as specified by the model, and also provide the model with user input from the view.
- Model. The model specifies the structure of the app's data and the code to access and manipulate the data. Some of the apps you create in the lessons work with models for accessing data. The Hello Toast app does not use a data model, but you can think of its logic — display a message, and increase a tap counter — as the model.
Views
The UI consists of a hierarchy of objects called views — every element of the screen is a view. The View class represents the basic building block for all UI components, and the base class for classes that provide interactive UI components such as buttons, checkboxes, and text entry fields.
A view has a location, expressed as a pair of left and top coordinates, and two dimensions, expressed as a width and a height. The unit for location and dimensions is the device-independent pixel (dp).
The Android system provides hundreds of predefined views, including those that display:
- Text (TextView)
- Fields for entering and editing text (EditText)
- Buttons users can tap (Button) and other interactive components
- Scrollable text (ScrollView) and scrollable items (RecyclerView)
- Images (ImageView)
You can define a view to appear on the screen and respond to a user tap. A view can also be defined to accept text input, or to be invisible until needed.
You can specify the views in XML layout resource files. Layout resources are written in XML and listed within the layout folder in the res folder in the Project: Android view.
View groups
Views can be grouped together inside a view group (ViewGroup), which acts as a container of views. The relationship is parent-child, in which the parent is a view group, and the child is a view or view group within the group. The following are common view groups:
- ScrollView: A group that contains one other child view and enables scrolling the child view.
- RecyclerView: A group that contains a list of other views or view groups and enables scrolling them by adding and removing views dynamically from the screen.
Layout view groups
The views for a screen are organized in a hierarchy. At the root of this hierarchy is a ViewGroup that contains the layout of the entire screen. The view group's child screens can be other views or other view groups as shown in the following figure.
In the above figure:
- The root view group.
- The first set of child views and view groups whose parent is the root.
Some view groups are designated as layouts because they organize child views in a specific way and are typically used as the root view group. Some examples of layouts are:
- LinearLayout: A group of child views positioned and aligned horizontally or vertically.
- RelativeLayout: A group of child views in which each view is positioned and aligned relative to other views within the view group. In other words, the positions of the child views can be described in relation to each other or to the parent view group.
- ConstraintLayout: A group of child views using anchor points, edges, and guidelines to control how views are positioned relative to other elements in the layout. ConstraintLayout was designed to make it easy to drag and drop views in the layout editor.
- TableLayout: A group of child views arranged into rows and columns.
- AbsoluteLayout: A group that lets you specify exact locations (x/y coordinates) of its child views. Absolute layouts are less flexible and harder to maintain than other types of layouts without absolute positioning.
- FrameLayout: A group of child views in a stack. FrameLayout is designed to block out an area on the screen to display one view. Child views are drawn in a stack, with the most recently added child on top. The size of the FrameLayout is the size of its largest child view.
- GridLayout: A group that places its child screens in a rectangular grid that can be scrolled.
Tip: Learn more about different layout types in Common Layout Objects.
A simple example of a layout with child views is the Hello Toast app in one of the early lessons. The view for the Hello Toast app appears in the figure below as a diagram of the layout file (activity_main.xml), along with a hierarchy diagram (top right) and a screenshot of the actual finished layout (bottom right).
In the figure above:
- LinearLayout root layout, which contains all the child views, set to a vertical orientation.
- Button (
button_toast
) child view. As the first child view, it appears at the top in the linear layout. - TextView (
show_count
) child view. As the second child view, it appears under the first child view in the linear layout. - Button (
button_count
) child view. As the third child view, it appears under the second child view in the linear layout.
The view hierarchy can grow to be complex for an app that shows many views on a screen. It's important to understand the view hierarchy, as it affects whether views are visible and efficiently they are drawn.
Tip: You can explore the view hierarchy of your app using Hierarchy Viewer. It shows a tree view of the hierarchy and lets you analyze the performance of views on an Android device. Performance issues are covered in a subsequent chapter.
You define views in the layout editor, or by entering XML code. The layout editor shows a visual representation of XML code.
Using the layout editor
Use the layout editor to edit the layout file. You can drag and drop view objects into a graphical pane, and arrange, resize, and specify properties for them. You immediately see the effect of changes you make.
To use the layout editor, open the XML layout file. The layout editor appears with the Design tab at the bottom highlighted. (If the Text tab is highlighted and you see XML code, click the Design tab.) For the Empty Activity template, the layout is as shown in the figure below.
In the figure above:
- XML layout file. The XML layout file, typically named activiy_main.xml file. Double-click it to open the layout editor.
- Palette of UI elements (views). The Palette pane provides a list of UI elements and layouts. Add an element or layout to the UI by dragging it into the design pane.
Design toolbar. The design pane toolbar provides buttons to configure your layout appearance in the design pane and to edit the layout properties. See the figure below for details.
Tip: Hover over each icon to view a tooltip that summarizes its function.
- Properties pane. The Properties pane provides property controls for the selected view.
- Property control. Property controls correspond to XML attributes. Shown in the figure is the
Text
property of the selected TextView, set toHello World!
. - Design pane. Drag views from the Palette pane to the design pane to position them in the layout.
- Component Tree. The Component Tree pane shows the view hierarchy. Click a view or view group in this pane to select it. The figure shows the TextView selected.
- Design and Text tabs. Click Design to see the layout editor, or Text to see XML code.
The layout editor's design toolbar offers a row of buttons that let you configure the appearance of the layout:
In the figure above:
- Design, Blueprint, and Both: Click the Design icon (first icon) to display a color preview of your layout. Click the Blueprint icon (middle icon) to show only outlines for each view. You can see both views side by side by clicking the third icon.
- Screen orientation: Click to rotate the device between landscape and portrait.
- Device type and size: Select the device type (phone/tablet, Android TV, or Android Wear) and screen configuration (size and density).
- API version: Select the version of Android on which to preview the layout.
- App theme: Select which UI theme to apply to the preview.
- Language: Select the language to show for your UI strings. This list displays only the languages available in the string resources.
- Layout Variants: Switch to one of the alternative layouts for this file, or create a new one.
The layout editor offers more features in the Design tab when you use a ConstraintLayout, including handles for defining constraints. A constraint is a connection or alignment to another view, to the parent layout, or to an invisible guideline. Each constraint appears as a line extending from a circular handle. Each view has a circular constraint handle in the middle of each side. After selecting a view in the Component Tree pane or clicking on it in the layout, the view also shows resizing handles on each corner.
In the above figure:
- Resizing handle.
- Constraint line and handle. In the figure, the constraint aligns the left side of the view to the left side of the button.
- Baseline handle. The baseline handle aligns the text baseline of a view to the text baseline of another view.
- Constraint handle without a constraint line.
Using XML
It is sometimes quicker and easier to edit the XML code directly, especially when copying and pasting the code for similar views.
To view and edit the XML code, open the XML layout file. The layout editor appears with the Design tab at the bottom highlighted. Click the Text tab to see the XML code. The following shows an XML code snippet of a LinearLayout with a Button and a TextView:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
... >
<Button
android:id="@+id/button_toast"
android:layout_width="@dimen/my_view_width"
android:layout_height="wrap_content"
... />
<TextView
android:id="@+id/show_count"
android:layout_width="@dimen/my_view_width"
android:layout_height="@dimen/counter_height"
... />
...
</LinearLayout>
XML attributes (view properties)
Views have properties that define where a view appears on the screen, its size, how the view relates to other views, and how it responds to user input. When defining views in XML, the properties are referred to as attributes.
For example, in the following XML description of a TextView, the android:id
, android:layout_width
, android:layout_height
, android:background
, are XML attributes that are translated automatically into the TextView's properties:
<TextView
android:id="@+id/show_count"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/myBackgroundColor"
android:textStyle="bold"
android:text="@string/count_initial_value"
/>
Attributes generally take this form:
android:attribute_name="value"
The attribute_name is the name of the attribute. The value is a string with the value for the attribute. For example:
android:textStyle="bold"
If the value is a resource, such as a color, the @
symbol specifies what kind of resource. For example:
android:background="@color/myBackgroundColor"
The background attribute is set to the color resource identified as myBackgroundColor
, which is declared to be #FFF043
. Color resources are described in "Style-related attributes" in this chapter.
Every view and view group supports its own variety of XML attributes. Some attributes are specific to a view (for example, TextView supports the textSize
attribute), but these attributes are also inherited by any views that may extend the TextView class. Some are common to all views, because they are inherited from the root View class (like the android:id
attribute). For descriptions of specific attributes, see the overview section of the View class documentation.
Identifying a view
To uniquely identify a view and reference it from your code, you must give it an id. The android:id
attribute lets you specify a unique id
— a resource identifier for a view.
For example:
android:id="@+id/button_count"
The "@+id/button_count"
part of the above attribute creates a new id
called button_count
for the view. You use the plus (+
) symbol to indicate that you are creating a new id
.
Referencing a view
To refer to an existing resource identifier, omit the plus (+
) symbol. For example, to refer to a view by its id
in another attribute, such as android:layout_toLeftOf
(described in the next section) to control the position of a view, you would use:
android:layout_toLeftOf="@id/show_count"
In the above attribute, "@id/show_count"
refers to the view with the resource identifier show_count
. The attribute positions the view to be "to the left of" the show_count
view.
Positioning views
Some layout-related positioning attributes are required for a view, and automatically appear when you add the view to the XML layout, ready for you to add values.
LinearLayout positioning
For example, LinearLayout is required to have these attributes set:
The android:layout_width
and android:layout_height
attributes can take one of three values:
match_parent
expands the view to fill its parent by width or height. When the LinearLayout is the root view, it expands to the size of the device screen. For a view within a root view group, it expands to the size of the parent view group.wrap_content
shrinks the view dimensions just big enough to enclose its content. (If there is no content, the view becomes invisible.)- Use a fixed number of
dp
(device-independent pixels) to specify a fixed size, adjusted for the screen size of the device. For example,16dp
means 16 device-independent pixels. Device-independent pixels and other dimensions are described in "Dimensions" in this chapter.
The android:orientation
can be:
horizontal:
Views are arranged from left to right.vertical:
Views are arranged from top to bottom.
Other layout-related attributes include:
Android:layout_gravity
: This attribute is used with a view to control where the view is arranged within its parent view group. For example, the following attribute centers the view horizontally on the screen:android:layout_gravity="center_horizontal"
- Padding is the space, measured in device-independent pixels, between the edges of the view and the view's content, as shown in the figure below.
In the figure above:
- Padding is the space between the edges of the view (dashed lines) and the view's content (solid line). Padding is not the same as margin, which is the space from the edge of the view to its parent.
A view's size includes its padding. The following are commonly used padding attributes:
Android:padding
: Sets the padding of all four edges.android:paddingTop
: Sets the padding of the top edge.android:paddingBottom
: Sets the padding of the bottom edge.android:paddingLeft
: Sets the padding of the left edge.android:paddingRight
: Sets the padding of the right edge.android:paddingStart
: Sets the padding of the start of the view; used in place of the above, especially with views that are long and narrow.android:paddingEnd
: Sets the padding, in pixels, of the end edge; used along withandroid:paddingStart
.
Tip: To see all of the XML attributes for a LinearLayout, see the Summary section of the LinearLayout reference in the Developer Guide. Other root layouts, such as RelativeLayout and AbsoluteLayout, list their XML attributes in the Summary sections.
RelativeLayout Positioning
Another useful view group for layout is RelativeLayout, which you can use to position child views relative to each other or to the parent. The attributes you can use with RelativeLayout include the following:
- android:layout_toLeftOf: Positions the right edge of this view to the left of another view (identified by its
ID
). - android:layout_toRightOf: Positions the left edge of this view to the right of another view (identified by its
ID
). - android:layout_centerHorizontal: Centers this view horizontally within its parent.
- android:layout_centerVertical: Centers this view vertically within its parent.
- android:layout_alignParentTop: Positions the top edge of this view to match the top edge of the parent.
- android:layout_alignParentBottom: Positions the bottom edge of this view to match the bottom edge of the parent.
For a complete list of attributes for views in a RelativeLayout, see RelativeLayout.LayoutParams.
Style-related attributes
You specify style attributes to customize the view's appearance. Views that don't have style attributes, such as android:textColor
, android:textSize
, and android:background
, take on the styles defined in the app's theme.
The following are style-related attributes used in the XML layout example in the previous section:
Android:background
: Specifies a color or drawable resource to use as the background.android:text
: Specifies text to display in the view.android:textColor
: Specifies the text color.android:textSize
: Specifies the text size.android:textStyle
: Specifies the text style, such asbold
.
Resource files
Resource files are a way of separating static values from code so that you don't have to change the code itself to change the values. You can store all the strings, layouts, dimensions, colors, styles, and menu text separately in resource files.
Resource files are stored in folders located in the res folder, including:
- drawable: For images and icons
- layout: For layout resource files
- menu: For menu items
- mipmap: For pre-calculated, optimized collections of app icons used by the Launcher
- values: For colors, dimensions, strings, and styles (theme attributes)
The syntax to reference a resource in an XML layout is as follows:
@package_name:resource_type/resource_name
- The package_name is the name of the package in which the resource is located. This is not required when referencing resources from the same package — that is, stored in the res folder of your project.
- resource_type is the
R
subclass for the resource type. See Resource Types for more information about each resource type and how to reference them. - resource_name is either the resource filename without the extension, or the
android:name
attribute value in the XML element.
For example, the following XML layout statement sets the android:text
attribute to a string
resource:
android:text="@string/button_label_toast"
- The resource_type is
string
. - The resource_name is
button_label_toast.
- There is no need for a package_name because the resource is stored in the project (in the strings.xml file).
Another example: this XML layout statement sets the android:background
attribute to a color
resource, and since the resource is defined in the project (in the colors.xml file), the package_name is not specified:
android:background="@color/colorPrimary"
In the following example, the XML layout statement sets the android:textColor
attribute to a color
resource. However, the resource is not defined in the project but supplied by Android, so the package_name android
must also be specified, followed by a colon:
android:textColor="@android:color/white"
Tip: For more information about accessing resources from code, see Accessing Resources. For Android color constants, see the Android standard R.color resources.
Values resource files
Keeping values such as strings and colors in separate resource files makes it easier to manage them, especially if you use them more than once in your layouts.
For example, it is essential to keep strings in a separate resource file for translating and localizing your app, so that you can create a string resource file for each language without changing your code. Resource files for images, colors, dimensions, and other attributes are handy for developing an app for different device screen sizes and orientations.
Strings
String resources are located in the strings.xml file in the values folder inside the res folder when using the Project: Android view. You can edit this file directly by opening it:
<resources>
<string name="app_name">Hello Toast</string>
<string name="button_label_count">Count</string>
<string name="button_label_toast">Toast</string>
<string name="count_initial_value">0</string>
</resources>
The name
(for example, button_label_count
) is the resource name you use in your XML code, as in the following attribute:
android:text="@string/button_label_count"
The string value of this name
is the word (Count
) enclosed within the <string></string>
tags (you don't use quotation marks unless the quotation marks should be part of the string value.)
Extracting strings to resources
You should also extract hard-coded strings in an XML layout file to string resources. To extract a hard-coded string in an XML layout, follow these steps (refer to the figure):
- Click on the hard-coded string, and press Alt-Enter in Windows, or Option-Return on Mac OS X.
- Select Extract string resource.
- Edit the Resource name for the string value.
You can then use the resource name in your XML code. Use the expression "@string/resource_name"
(including quotation marks) to refer to the string resource:
android:text="@string/button_label_count"
Colors
Color resources are located in the colors.xml file in the values folder inside the res folder when using the Project: Android view. You can edit this file directly:
<resources>
<color name="colorPrimary">#3F51B5</color>
<color name="colorPrimaryDark">#303F9F</color>
<color name="colorAccent">#FF4081</color>
<color name="myBackgroundColor">#FFF043</color>
</resources>
The name
(for example, colorPrimary
) is the resource name you use in your XML code:
android:textColor="@color/colorPrimary"
The color value of this name
is the hexadecimal color value (#3F51B5
) enclosed within the <color></color>
tags. The hexadecimal value specifies red, green, and blue (RGB) values. The value always begins with a pound (#
) character, followed by the Alpha-Red-Green-Blue information. For example, the hexadecimal value for black is #000000, while the hexadecimal value for a variant of sky blue is #559fe3. Base color values are listed in the Color class documentation.
The colorPrimary
color is one of the predefined base colors and is used for the app bar. In a production app, you could, for example, customize this to fit your brand. Using the base colors for other UI elements creates a uniform UI.
Tip: For the material design specification for Android colors, see Style and Using the Material Theme. For common color hexadecimal values, see Color Hex Color Codes. For Android color constants, see the Android standard R.color resources.
You can see a small block of the color choice in the left margin next to the color resource declaration in colors.xml, and also in the left margin next to the attribute that uses the resource name in the layout XML file.
Tip: To see the color in a popup, turn on the Autopopup documentation feature. Choose Android Studio > Preferences > Editor > General > Code Completion, and check the "Autopopup documentation in (ms)" option. You can then hover your cursor over a color resource name to see the color.
Dimensions
Dimensions should be separated from the code to make them easier to manage, especially if you need to adjust your layout for different device resolutions. It also makes it easy to have consistent sizing for views, and to change the size of multiple views by changing one dimension resource.
Dimension resources are located in a dimens.xml file in the values folder inside the res folder when using the Project: Android view. The dimens.xml shown in the view can be a folder holding more than one dimens.xml file for different device resolutions. For example, the app created from the Empty Activity template provides a second dimens.xml file for 820dp.
You can edit this file directly by opening it:
<resources>
<!-- Default screen margins, per the Android Design guidelines. -->
<dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen>
<dimen name="my_view_width">300dp</dimen>
<dimen name="count_text_size">200sp</dimen>
<dimen name="counter_height">300dp</dimen>
</resources>
The name
(for example, activity_horizontal_margin
) is the resource name you use in the XML code:
android:paddingLeft="@dimen/activity_horizontal_margin"
The value of this name
is the measurement (16dp
) enclosed within the <dimen></dimen>
tags.
You can extract dimensions in the same way as strings::
- Click on the hard-coded dimension, and press Alt-Enter in Windows, or press Option-Return on Mac OS X.
- Select Extract dimension resource.
- Edit the Resource name for the dimension value.
Device-independent pixels (dp
) are independent of screen resolution. For example, 10px
(10 fixed pixels) will look a lot smaller on a higher resolution screen, but Android will scale 10dp
(10 device-independent pixels) to look right on different resolution screens. Text sizes can also be set to look right on different resolution screens using scaled-pixel (sp
) sizes.
Tip: For more information about dp
and sp
units, see Supporting Different Densities.
Styles
A style is a resource that specifies common attributes such as height, padding, font color, font size, background color. Styles are meant for attributes that modify the look of the view.
Styles are defined in the styles.xml file in the values folder inside the res folder when using the Project: Android view. You can edit this file directly. Styles are covered in a later chapter, along with the Material Design Specification.
Other resource files
Android Studio defines other resources that are covered in other chapters:
- Images and icons. The drawable folder provides icon and image resources. If your app does not have a drawable folder, you can manually create it inside the res folder. For more information about drawable resources, see Drawable Resources in the App Resources section of the Android Developer Guide.
- Optimized icons. The mipmap folder typically contains pre-calculated, optimized collections of app icons used by the Launcher. Expand the folder to see that versions of icons are stored as resources for different screen densities.
- Menus. You can use an XML resource file to define menu items and store them in your project in the menu folder. Menus are described in a later chapter.
Responding to view clicks
A click event occurs when the user taps or clicks a clickable view, such as a Button, ImageButton, ImageView (tapping or clicking the image), or FloatingActionButton.
The model-view-presenter pattern is useful for understanding how to respond to view clicks. When an event occurs with a view, the presenter code performs an action that affects the model code. In order to make this pattern work, you have to:
- Write a Java method that performs the specific action, which is determined by the logic of the model code — that is, the action depends on what you want the app to do when this event occurs. This is typically referred to as an event handler.
- Associate this event handler method to the view, so that the method executes when the event occurs.
The onClick attribute
Android Studio provides a shortcut for setting up a clickable view, and for associating an event handler with the view: use the android:onClick
attribute with the clickable view's element in the XML layout.
For example, the following XML expression in the layout file for a Button sets showToast()
as the event handler:
android:onClick="showToast"
When the b
utton is tapped, its android:onClick
attribute calls the showToast()
method.
Write the event handler, such as showToast()
referenced in the XML code above, to call other methods that implement the app's model logic:
public void showToast(View view) {
// Do something in response to the button click.
}
In order to work with the android:onClick
attribute, the showToast()
method must be public
, return void
, and require a view
parameter in order to know which view called the method.
Android Studio provides a shortcut for creating an event handler stub (a placeholder for the method that you can fill in later) in the Java code for the activity associated with the XML layout. Follow these steps:
- Inside the XML layout file (such as activity_main.xml), click the method name in the
android:onClick
attribute statement. - Press Alt-Enter in Windows or Option-Return in Mac OS X, and select Create onClick event handler.
- Choose the activity associated with the layout file (such as MainActivity) and click OK. This creates a placeholder method stub in MainActivity.java.
Updating views
To update a view's contents, such as replacing the text in a TextView, your code must first instantiate an object from the view. Your code can then update the object, thereby updating the view.
To refer to the view in your code, use the findViewById() method of the View class, which looks for a view based on the resource id
. For example, the following statement sets mShowCount
to be the TextView with the resource id show_count
:
mShowCount = (TextView) findViewById(R.id.show_count);
From this point on, your code can use mShowCount
to represent the TextView, so that when you update mShowCount
, the view is updated.
For example, when the following button with the android:onClick
attribute is tapped, onClick calls the countUp()
method:
android:onClick="countUp"
You can implement countUp()
to increment the count, convert the count to a string, and set the string as the text for the mShowCount
object:
public void countUp(View view) {
mCount++;
if (mShowCount != null)
mShowCount.setText(Integer.toString(mCount));
}
Since you had already associated mShowCount
with the TextView for displaying the count, the mShowCount.setText()
method updates the text view on the screen.
Related practical
The related exercises and practical documentation is in Android Developer Fundamentals: Practicals.
Learn more
- Android Studio documentation:
- Android API Guide, "Develop" section:
- Material Design:
- Other:
- Android Studio User's Guide: Image Asset Studio
- Model-View-Presenter (MVP) architecture pattern
- Hierarchy Viewer for visualizing the view hierarchy
- Color Hex Color Codes